package net.lb.io.json.util;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import net.lb.io.json.annotation.Ignore;
import net.lb.io.json.field.BooleanField;
import net.lb.io.json.field.ByteField;
import net.lb.io.json.field.CharField;
import net.lb.io.json.field.DoubleField;
import net.lb.io.json.field.FloatField;
import net.lb.io.json.field.IntField;
import net.lb.io.json.field.JsonField;
import net.lb.io.json.field.LongField;
import net.lb.io.json.field.ObjectField;
import net.lb.io.json.field.ShortField;
import net.lb.io.json.serializer.FieldContainerSerializer;

public class JsonAnalyser
{
    public synchronized static void analyse(Class<?> type)
    {
        if (JsonConfig.containsSerializer(type))
        {
            return;
        }
        Class<?> oriType = type;
        ArrayList<Field> list = new ArrayList<>();
        while (!type.equals(Object.class))
        {
            for (Field field : type.getDeclaredFields())
            {
                list.add(field);
            }
            type = type.getSuperclass();
        }
        JsonField[] jsonFields = new JsonField[list.size()];
        int index = 0;
        for (Field field : list)
        {
            if (Modifier.isFinal(field.getModifiers()) || Modifier.isStatic(field.getModifiers()) || field.isAnnotationPresent(Ignore.class))
            {
                continue;
            }
            Class<?> fieldType = field.getType();
            while (fieldType.isArray())
            {
                fieldType = fieldType.getComponentType();
            }
            if (fieldType.equals(boolean.class))
            {
                jsonFields[index] = new BooleanField(field);
            }
            else if (fieldType.equals(byte.class))
            {
                jsonFields[index] = new ByteField(field);
            }
            else if (fieldType.equals(char.class))
            {
                jsonFields[index] = new CharField(field);
            }
            else if (fieldType.equals(double.class))
            {
                jsonFields[index] = new DoubleField(field);
            }
            else if (fieldType.equals(float.class))
            {
                jsonFields[index] = new FloatField(field);
            }
            else if (fieldType.equals(int.class))
            {
                jsonFields[index] = new IntField(field);
            }
            else if (fieldType.equals(long.class))
            {
                jsonFields[index] = new LongField(field);
            }
            else if (fieldType.equals(short.class))
            {
                jsonFields[index] = new ShortField(field);
            }
            // else if (Collection.class.isAssignableFrom(fieldType))
            // {
            // jsonFields[index] = new CollectionField(field);
            // }
            // else if (Map.class.isAssignableFrom(fieldType))
            // {
            // jsonFields[index] = new MapField(field);
            // }
            else
            {
                jsonFields[index] = new ObjectField(field);
            }
            index++;
        }
        FieldContainerSerializer jsonSerializer = new FieldContainerSerializer();
        JsonConfig.putSerializer(oriType, jsonSerializer);
        // 有些field不符合要求就会被排除。所以这里需要进行数组的转换。
        JsonField[] result = new JsonField[index];
        System.arraycopy(jsonFields, 0, result, 0, index);
        jsonSerializer.setJsonFields(result);
    }
}
